<?php

namespace Base;

use \Mapper\AdminModel as AdminMapper;

/**
 * 控制器的基类.
 */
class AbstractController extends \Yaf\Controller_Abstract {

    /**
     * 布局模板的名称
     *
     * @var sting
     */
    protected $layout = 'default';

    /**
     * 自动开启视图引擎及布局模块
     *
     * @var boolean
     */
    protected $autoRender = true;
    protected $autoLayout = true;

    /**
     * Layout 的目录是否跟随 Module 到对应的目录.
     *
     * @var boolean
     */
    protected $layoutFollowModule = false;

    /**
     * @return void
     */
    public function init() {
        if (method_exists($this, 'before') && $this->before() === false) {
            $this->disableLayout();
            $this->disableView();

            throw new \Exception('init failed!', 400);
        }

        ($this->autoRender === true && $this->autoLayout === true) ? $this->initView() : ($this->disableView() && $this->disableLayout());
        method_exists($this, 'after') && $this->after();
    }

    protected function before() {}
    protected function after() {
        /*if (!$this->_checkIp()) {
            $this->redirect('/');
        }*/
        $adminModel = $this->getloginAdmin();

        if (!$adminModel && 'login' !== $this->getRequest()->getActionName() &&
            'admin' !== $this->getRequest()->getControllerName()) {
            $this->redirect('/admin/admin/login');
        }

        $this->assign('adminModel',$adminModel);
    }

    /**
     * Session
     *
     * @return \Yaf\Session
     */
    public function getSession() {
        return \Yaf\Session::getInstance();
    }

    /**
     * 视图路径配置
     *
     * @param array $options
     * @return \Lib\Layout
     */
    public function initView(array $options = NULL) {
        parent::initView($options);
        $view = $this->getView();

        if (!empty($this->layout) && $this->autoLayout === true) {
            $config  = $this->getConfig();
            $prePath = $config->get('application.directory');

            if ($this->layoutFollowModule && 'Index' !== $this->getModuleName()) {
                $prePath .= 'modules' . DS . $this->getModuleName() . DS;
            }

            $view->setLayoutPath($prePath . 'views' . DS . 'layouts');
            $view->setLayout($this->layout);
            $this->initResources();
        }

        return $view;
    }

    /**
     * 处理资源路径
     *
     * @throws \Exception
     */
    protected function initResources() {
        $config   = \Yaf\Registry::get('config');
        $resource = $config->get('resources.static');

        if (!$resource instanceof \Yaf\Config\Ini) {
            throw new \Exception('invalid static resources INIT');
        }

        $baseURL       = trim((string)$resource->get('baseURL'), '/') . '/';
        $imageURI      = trim((string)$resource->get('imageURI'), '/') . '/';
        $styleURI      = trim((string)$resource->get('styleURI'), '/') . '/';
        $javascriptURI = trim((string)$resource->get('scriptURI'), '/') . '/';

        $this->assign('baseURL', $baseURL);
        $this->assign('imageURL', $baseURL . $imageURI);
        $this->assign('styleURL', $baseURL . $styleURI);
        $this->assign('scriptURL', $baseURL . $javascriptURI);
        $this->assign('mainDomain', rtrim($config->get('resources.main.domain'), '/') . '/');
    }

    /**
     * 取得当前配置
     *
     * @return \Yaf\Config\Ini
     */
    public function getConfig() {
        return \Yaf\Application::app()->getConfig();
    }

    /**
     * 向视图注册属性(变量)
     *
     * @param string  $name   属性名
     * @param mixed         $value  属性值
     * @return boolean
     */
    public function assign($name, $value) {
        $this->getView()->assign($name, $value);

        return $this;
    }

    /**
     * 向视图注册属性(变量)
     *
     * @param array|object  $options 属性
     * @return boolean
     */
    public function assigneach($options) {
        if (is_object($options)) {
            if (method_exists($options, 'toArray')) {
                $options = $options->toArray();
            } else if (!($options instanceof \Traversable)) {
                return $this;
            }
        } else if (!is_array($options)) {
            return $this;
        }

        $view = $this->getView();

        foreach ($options as $key => $value) {
            $view->assign($key, $value);
        }

        return $this;
    }

    /**
     * 关闭模板的默认渲染设置
     *
     * @return bool
     */
    public function disableView() {
        return \Yaf\Dispatcher::getInstance()->disableView();
    }

    /**
     * 关闭模板布局
     */
    public function disableLayout() {
        $this->getView()->setLayout(null);
    }

    /**
     * 修改布局
     *
     * @param string $layout
     * @return true
     */
    public function setLayout($layout) {
        $this->layout = $layout;

        return true;
    }

    /**
     * 扔掉视图自动渲染
     *
     * @return boolean
     */
    public function dropAutoRender() {
        $this->autoRender = false;
        $this->autoLayout = false;

        return true;
    }

    /**
     * Redirect Url
     *
     * @return string
     */
    protected function getRedirectUrl(){
        $request     = $this->getRequest();
        $redirectUrl = trim(urldecode($request->getPost('redirect_url', null))) ?: trim($request->get('redirect_url', null));

        if(empty($redirectUrl) || strpos($redirectUrl, '//') === 0 || strpos($redirectUrl, '\\') !== false || strpos($redirectUrl, '@') !== false) {
           return '/';
        }

        if(strpos($redirectUrl, '/') === 0) {
            return \Lib\Tool::strReplace($redirectUrl);
        }

        $domainConfig = new \Yaf\Config\Ini(\APPLICATION_PATH . '/conf/domain.ini', \Yaf\Application::app()->environ());
        $domainIni    = $domainConfig->get('list');

        if($domainIni instanceof \Yaf\Config\Ini) {
            $domainList = $domainIni->toArray();
            $params     = parse_url($redirectUrl);

            if(isset($params['host']) && in_array($params['host'], $domainList)) {
                $url = \Lib\Tool::strReplace($redirectUrl);
            }
        }

        return (isset($url) ? $url : '/');
    }

    /**
     * IP白名单
     *
     * @return boolean
     */
    protected function inIpWhitelist() {
        $whitelist = \Yaf\Registry::get('ipwhitelist')->get('list');

        if (!$whitelist instanceof \Yaf\Config\Ini) {
            return false;
        }

        return (bool)\Lib\Tool::isInNetwork(\Lib\Tool::getClientIp(), $whitelist->toArray());
    }

    /**
     * @desc 获取当前已登录的管理员对象
     *
     * @return bool
     */
    public function getLoginAdmin() {
        $sessionAdmin = $this->getSession()->get('Admin');

        if (empty($sessionAdmin)) {
            return false;
        }

        if (!is_array($sessionAdmin)) {
            return false;
        }

        if (!isset($sessionAdmin['id']) or ! isset($sessionAdmin['ip'])) {
            return false;
        }

        if (1 > $sessionAdmin['id']) {
            return false;
        }

        $adminModel = AdminMapper::getInstance()->findById($sessionAdmin['id']);

        if (!($adminModel instanceof \AdminModel)) {
            return false;
        }

        if ($adminModel->getStatus()!==1) {
            return false;
        }

        /*if (\Lib\Tool::getClientIp(true) !== $sessAdmin['ip']) {
            return false;
        }*/

        return $adminModel;
    }
}
